<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns:MSHelp="http://www.microsoft.com/MSHelp/" lang="en-us" xml:lang="en-us"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta name="DC.Type" content="reference">
<meta name="DC.Title" content="affinity_partitioner">
<meta name="DC.subject" content="affinity_partitioner">
<meta name="keywords" content="affinity_partitioner">
<meta name="DC.Relation" scheme="URI" content="../../../reference/algorithms/partitioners.htm">
<meta name="DC.Format" content="XHTML">
<meta name="DC.Identifier" content="affinity_partitioner">
<meta name="DC.Language" content="en-US">
<link rel="stylesheet" type="text/css" href="../../../intel_css_styles.css">
<title>affinity_partitioner</title>
<xml>
<MSHelp:Attr Name="DocSet" Value="Intel"></MSHelp:Attr>
<MSHelp:Attr Name="Locale" Value="kbEnglish"></MSHelp:Attr>
<MSHelp:Attr Name="TopicType" Value="kbReference"></MSHelp:Attr>
</xml>
</head>
<body id="affinity_partitioner">
 <!-- ==============(Start:NavScript)================= -->
 <script src="..\..\..\NavScript.js" language="JavaScript1.2" type="text/javascript"></script>
 <script language="JavaScript1.2" type="text/javascript">WriteNavLink(3);</script>
 <!-- ==============(End:NavScript)================= -->
<a name="affinity_partitioner"><!-- --></a>


  <h1 class="topictitle1">affinity_partitioner</h1>
 
  
  <div> 
	 <div class="section"><h2 class="sectiontitle">Summary</h2> 
		 
		<p>Hint that loop iterations should be assigned to threads in a way that
		  optimizes for cache affinity.
		</p>
 
	 </div>
 
	 <div class="section"><h2 class="sectiontitle">Header</h2> 
		
		<pre>#include "tbb/partitioner.h"</pre> 
	 </div>
 
	 <div class="section"><h2 class="sectiontitle">Syntax</h2> 
		
		<pre> class affinity_partitioner;</pre>
	 </div>
 
	 <div class="section"><h2 class="sectiontitle">Description</h2> 
		 
		<p>An 
		  <samp class="codeph">affinity_partitioner</samp> hints that execution of a loop
		  template should assign iterations to the same processors as another execution
		  of the loop (or another loop) with the same 
		  <samp class="codeph">affinity_partitioner</samp> object.
		</p>

		<p>Unlike the other partitioners, it is important that the same 
		  <samp class="codeph">affinity_partitioner</samp> object be passed to the loop
		  templates to be optimized for affinity. The Tutorial section on "Bandwidth and
		  Cache Affinity" discusses affinity effects in detail. 
		</p>
 
		<div class="Note"><h3 class="NoteTipHead">
					Tip</h3>
		  <p> The affinity_partitioner generally improves performance only when: 
		  </p>

		  <ul type="disc">
			 <li>The computation does a few operations per data access.
			 </li>

			 <li>The data acted upon by the loop fits in cache.
			 </li>

			 <li> The loop, or a similar loop, is re-executed over the same data. 
			 </li>

			 <li>There are more than two hardware threads available.
			 </li>

		  </ul>

		</div>
	 </div>
 
	 <div class="section"><h2 class="sectiontitle">Members</h2> 
		
		<pre>
namespace tbb {
    class affinity_partitioner {
    public:
        affinity_partitioner();
        ~affinity_partitioner();
    }
}
</pre> 
	 </div>
 
	 <div class="section"><h2 class="sectiontitle">Example</h2> 
		
		<p>The following example can benefit from cache
		  affinity. The example simulates a one dimensional additive automaton.
		</p>

		<p> 
		  <pre>
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/partitioner.h"

using namespace tbb;

const int N = 1000000;
typedef unsigned char Cell;
Cell Array[2][N];
int FlipFlop;

struct TimeStepOverSubrange {
    void operator()( const blocked_range&lt;int&gt;&amp; r ) const {
        int j = r.end();
        const Cell* x = Array[FlipFlop];
        Cell* y = Array[!FlipFlop];
        for( int i=r.begin(); i!=j; ++i ) 
            y[i] = x[i]^x[i+1];
    }
};


void DoAllTimeSteps( int m ) {
    affinity_partitioner ap;
    for( int k=0; k&lt;m; ++k ) {
        parallel_for( blocked_range&lt;int&gt;(0,N-1), 
                      TimeStepOverSubrange(),
                      ap );
        FlipFlop ^= 1;
    }
}
</pre>
		</p>

		<p>For each time step, the old state of the automaton is read from 
		  <samp class="codeph">Array[FlipFlop]</samp>, and the new state is written into 
		  <samp class="codeph">Array[!FlipFlop]</samp>. Then 
		  <samp class="codeph">FlipFlop</samp> flips to make the new state become the old
		  state. The aggregate size of both states is about 2 MByte, which fits in most
		  modern processors' cache. Improvements ranging from 50%-200% have been observed
		  for this example on 8 core machines, compared with using an 
		  <samp class="codeph">auto_partitioner</samp> instead.
		</p>

		<p>The<samp class="codeph"> affinity_partitioner</samp> must live between loop
		  iterations. The example accomplishes this by declaring it outside the loop that
		  executes all iterations. An alternative would be to declare the 
		  <samp class="codeph">affinity partitioner</samp> at the file scope, which works as
		  long as 
		  <samp class="codeph">DoAllTimeSteps</samp> itself is not invoked concurrently. The
		  same instance of 
		  <samp class="codeph">affinity_partitioner</samp> should not be passed to two
		  parallel algorithm templates that are invoked concurrently. Use separate
		  instances instead.
		</p>
 
	 </div>
 
	 
<div class="tablenoborder"><table cellpadding="4" summary="" frame="border" border="1" cellspacing="0" rules="all"><span class="tabledesc">The following table provides additional information on the members
		  of this template class. 
		</span><thead align="left"> 
			 <tr> 
				<th class="cellrowborder" valign="top" width="33.89830508474576%" id="d9558e163">Member 
				</th>
 
				<th class="cellrowborder" valign="top" width="66.10169491525423%" id="d9558e166">Description 
				</th>
 
			 </tr>
</thead>
 
		  <tbody> 
			 <tr> 
				<td class="cellrowborder" valign="top" width="33.89830508474576%" headers="d9558e163 "><span class="keyword">affinity_partitioner()</span> 
				</td>
 
				<td class="cellrowborder" valign="top" width="66.10169491525423%" headers="d9558e166 "> 
				  <p> Construct an 
					 <samp class="codeph">affinity_partitioner</samp>. 
				  </p>
 
				</td>
 
			 </tr>
 
			 <tr> 
				<td class="cellrowborder" valign="top" width="33.89830508474576%" headers="d9558e163 "><span class="keyword">~affinity_partitioner()</span> 
				</td>
 
				<td class="cellrowborder" valign="top" width="66.10169491525423%" headers="d9558e166 "> 
				  <p>Destroy this 
					 <samp class="codeph">affinity_partitioner</samp>. 
				  </p>
 
				</td>
 
			 </tr>
 
		  </tbody>
 
		</table>
</div>
 
  </div>
 

<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong>&nbsp;<a href="../../../reference/algorithms/partitioners.htm">Partitioners</a></div>
</div>
<div></div>

</body>
</html>
